package com.dctp.common.utils;

import com.dctp.common.core.RedisManager;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;

public class IPUtil {

    private static final Logger logger = LoggerFactory.getLogger(IPUtil.class);

    /**
     * 获取用户真实IP地址，不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值
     *
     * @return ip
     */
        /**
         * 获取客户端真实 IP 地址
         * @param controller JFinal Controller 对象
         * @return 真实 IP 地址
         */
        public static String getClientIP(Controller controller) {

            HttpServletRequest request = controller.getRequest();
            String ip = null;
            // 1. 优先从 Nginx 代理头获取
            String[] headers = {
                    "X-Real-IP",          // Nginx 基础代理头
                    "X-Forwarded-For",     // 多层代理链
                    "Proxy-Client-IP",     // Apache 代理
                    "WL-Proxy-Client-IP",  // WebLogic 代理
                    "HTTP_CLIENT_IP",      // 其他代理
                    "HTTP_X_FORWARDED_FOR"
            };

            // 遍历代理头寻找有效 IP
            for (String header : headers) {
                ip = request.getHeader(header);
                if (isValidIP(ip)) {
                    break;
                }
            }

            // 2. 直接获取远端地址 (无代理时)
            if (!isValidIP(ip)) {
                ip = request.getRemoteAddr();
            }

            // 3. 处理多层代理的 X-Forwarded-For
            if (ip != null && ip.contains(",")) {
                ip = ip.split(",")[0].trim();
            }

            // 4. 本地测试处理 (127.0.0.1 或 0:0:0:0:0:0:0:1)
            if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
                try {
                    ip = InetAddress.getLocalHost().getHostAddress();
                } catch (UnknownHostException e) {
                    ip = "127.0.0.1"; // 保底返回
                }
            }
            return ip;
        }

        /**
         * 验证 IP 有效性
         */
        private static boolean isValidIP(String ip) {
            return ip != null && ip.length() > 0
                    && !"unknown".equalsIgnoreCase(ip)
                    && !ip.startsWith("192.168.")
                    && !ip.startsWith("10.")
                    && !ip.startsWith("172.16.")
                    && !ip.startsWith("169.254.");
        }


    private static void writeToTable(String ip,Integer type) {

        Long id = Db.queryLong("select id from dctp_ip_black_list where ip_addr = ? ",ip);
        if (null == id) {
            Record record = new Record();
            record.set("ip_addr",ip)
                    .set("type",type)
                    .set("create_time",new Date())
                    .set("status",0);
            if (!Db.save("dctp_ip_black_list",record)) {
                logger.error("写入黑名单失败");
            }
        }
    }

    public static void trace(String ip,Integer type) {

        try {
            Integer timesToBlackList = NumberUtil.parseInt(RedisManager.getInstance().get("timesToBlackList"),100);
            String key = ip + "_" + type;
            Long times = RedisManager.getInstance().incrBy(key,1L);
            if (times.intValue() >= timesToBlackList.intValue()) {
                writeToTable(ip,type);
            }
            RedisManager.getInstance().expire(key, 600);
        }catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }
}
